#include "io.h"
#include "platform.h"


void io_drv_init(void)
{
    gpio_init_type gpio_init_struct;

    /* enable the led clock */
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOD_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOH_PERIPH_CLOCK, TRUE);
    gpio_default_para_init(&gpio_init_struct);

    //INPUT

    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_INPUT;
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;

    //EC11 PB6,7,9  上升沿触发时对方电平为高表示旋转完成
    gpio_init_struct.gpio_pins = GPIO_PINS_6;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_init_struct.gpio_pins = GPIO_PINS_7;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_init_struct.gpio_pins = GPIO_PINS_9;
    gpio_init(GPIOB, &gpio_init_struct);

    //SD IN
    gpio_init_struct.gpio_pins = GPIO_PINS_3;
    gpio_init(GPIOH, &gpio_init_struct);

    //OUTPUT
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init_struct.gpio_out_type  = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_mode = GPIO_MODE_OUTPUT;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;

    //LED PC13
    gpio_init_struct.gpio_pins = GPIO_PINS_13;
    gpio_init(GPIOC, &gpio_init_struct);

    //BEEP PA8
    gpio_init_struct.gpio_pins = GPIO_PINS_8;
    gpio_init(GPIOA, &gpio_init_struct);

    //LCD
    gpio_init_struct.gpio_pull = GPIO_PULL_UP;

    //LCD BL PC9
    gpio_init_struct.gpio_pins = GPIO_PINS_9;
    gpio_init(GPIOC, &gpio_init_struct);

    //LCD RST
    gpio_init_struct.gpio_pins = GPIO_PINS_11;
    gpio_init(GPIOC, &gpio_init_struct);
    gpio_bits_set(GPIOC, GPIO_PINS_11);
    //LCD DC PC8
    gpio_init_struct.gpio_pins = GPIO_PINS_8;
    gpio_init(GPIOC, &gpio_init_struct);
    //LCD CS PA15
    gpio_init_struct.gpio_pins = GPIO_PINS_15;
    gpio_init(GPIOA, &gpio_init_struct);

    //EG1151 RST CTR
    gpio_init_struct.gpio_pins = GPIO_PINS_0;
    gpio_init(GPIOC, &gpio_init_struct);
    EG1151_DIS();

    //FLASH CS PD2
    gpio_init_struct.gpio_pins = GPIO_PINS_2;
    gpio_init(GPIOD, &gpio_init_struct);
    F_CS_H();

    //SD CS PB12
    gpio_init_struct.gpio_pins = GPIO_PINS_12;
    gpio_init(GPIOB, &gpio_init_struct);
    SD_CS_H();
    
    exint_init_type exint_init_struct;
    crm_periph_clock_enable(CRM_SCFG_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOB_PERIPH_CLOCK, TRUE);
    scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE6);
    exint_default_para_init(&exint_init_struct);
    exint_init_struct.line_enable = TRUE;
    exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
    exint_init_struct.line_select = EXINT_LINE_6;
    exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
    exint_init(&exint_init_struct);
    
    scfg_exint_line_config(SCFG_PORT_SOURCE_GPIOB, SCFG_PINS_SOURCE7);
    exint_default_para_init(&exint_init_struct);
    exint_init_struct.line_enable = TRUE;
    exint_init_struct.line_mode = EXINT_LINE_INTERRUPUT;
    exint_init_struct.line_select = EXINT_LINE_7;
    exint_init_struct.line_polarity = EXINT_TRIGGER_RISING_EDGE;
    exint_init(&exint_init_struct);

    nvic_irq_enable(EXINT9_5_IRQn, 1, 0);
}

__IO int16_t enc_flag = 0;

int16_t enc_flag_get(void)
{
    int16_t res = enc_flag;
    enc_flag = 0;
    return res;
}

void EXINT9_5_IRQHandler(void)
{
    if(exint_flag_get(EXINT_LINE_6) != RESET)
    {
        exint_flag_clear(EXINT_LINE_6);
        if(gpio_input_data_bit_read(GPIOB, GPIO_PINS_7) == SET)
        {
            //printf("ccw!!!\r\n");
            enc_flag = -1;
        }
    }
    else if(exint_flag_get(EXINT_LINE_7) != RESET)
    {
        exint_flag_clear(EXINT_LINE_7);
        if(gpio_input_data_bit_read(GPIOB, GPIO_PINS_6) == SET)
        {
            //printf("cw!!!\r\n");
            enc_flag = 1;
        }
    }
}

__IO uint16_t adc1_ordinary_valuetab[ADC_CHANNEL_NUM * ADC_FILT_NUM];
__IO uint16_t dma_trans_complete_flag = 0;

void adc_drv_init(void)
{
    //ADC
    gpio_init_type gpio_init_struct;
    dma_init_type dma_init_struct;
    adc_common_config_type adc_common_struct;
    adc_base_config_type adc_base_struct;

    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_ADC1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_DMA1_PERIPH_CLOCK, TRUE);

    nvic_irq_enable(DMA1_Channel1_IRQn, 0, 0);
    nvic_irq_enable(ADC1_2_3_IRQn, 0, 0);

    gpio_default_para_init(&gpio_init_struct);
    /* config adc pin as analog input mode */
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_pins = GPIO_PINS_1 | GPIO_PINS_2 | GPIO_PINS_3 | GPIO_PINS_6;
    gpio_init(GPIOA, &gpio_init_struct);

    dma_reset(DMA1_CHANNEL1);
    dma_default_para_init(&dma_init_struct);
    dma_init_struct.buffer_size = ADC_CHANNEL_NUM * ADC_FILT_NUM;
    dma_init_struct.direction = DMA_DIR_PERIPHERAL_TO_MEMORY;
    dma_init_struct.memory_base_addr = (uint32_t)adc1_ordinary_valuetab;
    dma_init_struct.memory_data_width = DMA_MEMORY_DATA_WIDTH_HALFWORD;
    dma_init_struct.memory_inc_enable = TRUE;
    dma_init_struct.peripheral_base_addr = (uint32_t) & (ADC1->odt);
    dma_init_struct.peripheral_data_width = DMA_PERIPHERAL_DATA_WIDTH_HALFWORD;
    dma_init_struct.peripheral_inc_enable = FALSE;
    dma_init_struct.priority = DMA_PRIORITY_MEDIUM;
    dma_init_struct.loop_mode_enable = TRUE;
    dma_init(DMA1_CHANNEL1, &dma_init_struct);

    dmamux_enable(DMA1, TRUE);
    dmamux_init(DMA1MUX_CHANNEL1, DMAMUX_DMAREQ_ID_ADC1);

    /* enable dma transfer complete interrupt */
    dma_interrupt_enable(DMA1_CHANNEL1, DMA_FDT_INT, TRUE);
    dma_channel_enable(DMA1_CHANNEL1, TRUE);

    adc_common_default_para_init(&adc_common_struct);

    /* config combine mode */
    adc_common_struct.combine_mode = ADC_INDEPENDENT_MODE;

    /* config division,adcclk is division by hclk */
    adc_common_struct.div = ADC_HCLK_DIV_4;

    /* config common dma mode,it's not useful in independent mode */
    adc_common_struct.common_dma_mode = ADC_COMMON_DMAMODE_DISABLE;

    /* config common dma request repeat */
    adc_common_struct.common_dma_request_repeat_state = FALSE;

    /* config adjacent adc sampling interval,it's useful for ordinary shifting mode */
    adc_common_struct.sampling_interval = ADC_SAMPLING_INTERVAL_5CYCLES;

    /* config inner temperature sensor and vintrv */
    adc_common_struct.tempervintrv_state = FALSE;

    /* config voltage battery */
    adc_common_struct.vbat_state = FALSE;
    adc_common_config(&adc_common_struct);

    adc_base_default_para_init(&adc_base_struct);
    adc_base_struct.sequence_mode = TRUE;
    adc_base_struct.repeat_mode = TRUE;
    adc_base_struct.data_align = ADC_RIGHT_ALIGNMENT;
    adc_base_struct.ordinary_channel_length = ADC_CHANNEL_NUM;
    adc_base_config(ADC1, &adc_base_struct);
    adc_resolution_set(ADC1, ADC_RESOLUTION_12B);
    /* 
        PA1 输入电压
        PA2 输入电流
        PA3 输出电压
        PA6 输出电流
    */

    /* config ordinary channel */
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_1, 1, ADC_SAMPLETIME_92_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_2, 2, ADC_SAMPLETIME_92_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_3, 3, ADC_SAMPLETIME_92_5);
    adc_ordinary_channel_set(ADC1, ADC_CHANNEL_6, 4, ADC_SAMPLETIME_92_5);

    /* config ordinary trigger source and trigger edge */
    adc_ordinary_conversion_trigger_set(ADC1, ADC_ORDINARY_TRIG_TMR1CH1, ADC_ORDINARY_TRIG_EDGE_NONE);

    /* config dma mode,it's not useful when common dma mode is use */
    adc_dma_mode_enable(ADC1, TRUE);

    /* config dma request repeat,it's not useful when common dma mode is use */
    adc_dma_request_repeat_enable(ADC1, TRUE);

    /* enable adc overflow interrupt */
    adc_interrupt_enable(ADC1, ADC_OCCO_INT, TRUE);

    /* adc enable */
    adc_enable(ADC1, TRUE);

    //while(adc_flag_get(ADC1, ADC_RDY_FLAG) == RESET);

    /* adc calibration */
    adc_calibration_init(ADC1);

    //while(adc_calibration_init_status_get(ADC1));

    adc_calibration_start(ADC1);

    //while(adc_calibration_status_get(ADC1));

    adc_ordinary_software_trigger_enable(ADC1, TRUE);
}

void dac_drv_init(void)
{
    //VOL SET PA4 DAC
    gpio_init_type gpio_init_struct;

    /* enable dac/gpioa clock */
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_DAC_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);
    /* once the dac is enabled, the corresponding gpio pin is automatically
     connected to the dac converter. in order to avoid parasitic consumption,
     the gpio pin should be configured in analog */
    gpio_init_struct.gpio_pins = GPIO_PINS_4;
    gpio_init_struct.gpio_mode = GPIO_MODE_ANALOG;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOA, &gpio_init_struct);

    /* dac1 configuration */
    dac_trigger_select(DAC1_SELECT, DAC_SOFTWARE_TRIGGER);
    dac_trigger_enable(DAC1_SELECT, TRUE);
    dac_wave_generate(DAC1_SELECT, DAC_WAVE_GENERATE_NONE);
    dac_mask_amplitude_select(DAC1_SELECT, DAC_LSFR_BITB0_AMPLITUDE_4095);
    dac_output_buffer_enable(DAC1_SELECT, TRUE);
    /* enable dac1: once the dac1 is enabled, pa.04 is
     automatically connected to the dac converter. */
    dac_enable(DAC1_SELECT, TRUE);
    dac_software_trigger_generate(DAC1_SELECT);
    dac_1_data_set(DAC1_12BIT_RIGHT, 4095);

    gpio_init_struct.gpio_pins = GPIO_PINS_5;
    gpio_init(GPIOA, &gpio_init_struct);
    /* dac2 configuration */
    dac_trigger_select(DAC2_SELECT, DAC_SOFTWARE_TRIGGER);
    dac_trigger_enable(DAC2_SELECT, TRUE);
    dac_wave_generate(DAC2_SELECT, DAC_WAVE_GENERATE_NONE);
    dac_mask_amplitude_select(DAC2_SELECT, DAC_LSFR_BITB0_AMPLITUDE_4095);
    dac_output_buffer_enable(DAC2_SELECT, TRUE);

    dac_enable(DAC2_SELECT, TRUE);
    dac_software_trigger_generate(DAC2_SELECT);
    dac_2_data_set(DAC2_12BIT_RIGHT, 4095);
}

void spi_drv_init(void)
{
    //LCD SPI
    gpio_init_type gpio_init_struct;
    spi_init_type spi_init_struct;

    /* enable dac/gpioa clock */
    crm_periph_clock_enable(CRM_GPIOC_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_SPI1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_SPI2_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_SPI3_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);

    /* sck */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_mode           = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins           = GPIO_PINS_10;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOC, &gpio_init_struct);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE10, GPIO_MUX_6);

    /* miso */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_11;
    gpio_init(GPIOC, &gpio_init_struct);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE11, GPIO_MUX_6);

    /* mosi */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_12;
    gpio_init(GPIOC, &gpio_init_struct);
    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE12, GPIO_MUX_6);

    spi_default_para_init(&spi_init_struct);
    spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
    spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
    spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_4;
    spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
    spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
    spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
    spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
    spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
    spi_init(SPI3, &spi_init_struct);
    spi_enable(SPI3, TRUE);

    //SPI FLASH
    /* sck */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_mode           = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins           = GPIO_PINS_3;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE3, GPIO_MUX_5);

    /* miso */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_4;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE4, GPIO_MUX_5);

    /* mosi */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_5;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE5, GPIO_MUX_5);

    spi_default_para_init(&spi_init_struct);
    spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
    spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
    spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_4;//9M very low
    spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
    spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
    spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
    spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
    spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
    spi_init(SPI1, &spi_init_struct);
    spi_enable(SPI1, TRUE);

    //SD CARD
    /* sck */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_mode           = GPIO_MODE_MUX;
    gpio_init_struct.gpio_pins           = GPIO_PINS_13;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE13, GPIO_MUX_5);

    /* miso */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_14;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE14, GPIO_MUX_5);

    /* mosi */
    gpio_init_struct.gpio_pull           = GPIO_PULL_UP;
    gpio_init_struct.gpio_pins           = GPIO_PINS_15;
    gpio_init(GPIOB, &gpio_init_struct);
    gpio_pin_mux_config(GPIOB, GPIO_PINS_SOURCE15, GPIO_MUX_5);

    spi_default_para_init(&spi_init_struct);
    spi_init_struct.transmission_mode = SPI_TRANSMIT_FULL_DUPLEX;
    spi_init_struct.master_slave_mode = SPI_MODE_MASTER;
    spi_init_struct.mclk_freq_division = SPI_MCLK_DIV_64;
    spi_init_struct.first_bit_transmission = SPI_FIRST_BIT_MSB;
    spi_init_struct.frame_bit_num = SPI_FRAME_8BIT;
    spi_init_struct.clock_polarity = SPI_CLOCK_POLARITY_HIGH;
    spi_init_struct.clock_phase = SPI_CLOCK_PHASE_2EDGE;
    spi_init_struct.cs_mode_selection = SPI_CS_SOFTWARE_MODE;
    spi_init(SPI2, &spi_init_struct);
    spi_enable(SPI2, TRUE);
}

void tmr_drv_init(void)
{
    gpio_init_type gpio_init_struct;
    tmr_output_config_type tmr_output_struct;
    tmr_output_config_type tmr_oc_init_structure;

    //lvlg drv tick
    crm_clocks_freq_type crm_clocks_freq_struct = {0};

    /* tmr6 interrupt nvic init */
    nvic_irq_enable(TMR6_DAC_GLOBAL_IRQn, 0, 3);

    /* get system clock */
    crm_clocks_freq_get(&crm_clocks_freq_struct);
    /* enable tmr6 clock */
    crm_periph_clock_enable(CRM_TMR6_PERIPH_CLOCK, TRUE);

    gpio_default_para_init(&gpio_init_struct);

    /* tmr6 configuration */
    /* time base configuration */
    tmr_base_init(TMR6, 999, 288 - 1);
    tmr_cnt_dir_set(TMR6, TMR_COUNT_UP);

    /* overflow interrupt enable */
    tmr_interrupt_enable(TMR6, TMR_OVF_INT, TRUE);

    /* enable tmr6 */
    tmr_counter_enable(TMR6, TRUE);

    //LCD BL
    /* tmr3 clock enable */
    crm_periph_clock_enable(CRM_TMR3_PERIPH_CLOCK, TRUE);

    gpio_init_struct.gpio_pins = GPIO_PINS_9;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOC, &gpio_init_struct);

    gpio_pin_mux_config(GPIOC, GPIO_PINS_SOURCE9, GPIO_MUX_2);

    /* compute the prescaler value */
    uint16_t prescalervalue = (uint16_t) ((crm_clocks_freq_struct.apb1_freq * 2) / 144000000) - 1;

    /* tmr3 time base configuration */
    tmr_base_init(TMR3, 10000, prescalervalue);
    tmr_cnt_dir_set(TMR3, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR3, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;

    tmr_output_channel_config(TMR3, TMR_SELECT_CHANNEL_4, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR3, TMR_SELECT_CHANNEL_4, 6000);	//60%
    tmr_output_channel_buffer_enable(TMR3, TMR_SELECT_CHANNEL_4, TRUE);

    tmr_period_buffer_enable(TMR3, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR3, TRUE);
    #if 0
    //MOS PWM CTR 20KHz
    /* tmr5 clock enable */
    crm_periph_clock_enable(CRM_TMR5_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOH_PERIPH_CLOCK, TRUE);

    gpio_init_struct.gpio_pins = GPIO_PINS_2;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOH, &gpio_init_struct);

    gpio_pin_mux_config(GPIOH, GPIO_PINS_SOURCE2, GPIO_MUX_2);

    /* tmr5 time base configuration 14400->20K 7200->40K */
    tmr_base_init(TMR5, 28800 - 1, 0);
    tmr_cnt_dir_set(TMR5, TMR_COUNT_UP);
    tmr_clock_source_div_set(TMR5, TMR_CLOCK_DIV1);

    tmr_output_default_para_init(&tmr_oc_init_structure);
    tmr_oc_init_structure.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_A;
    tmr_oc_init_structure.oc_idle_state = FALSE;
    tmr_oc_init_structure.oc_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_oc_init_structure.oc_output_state = TRUE;

    tmr_output_channel_config(TMR5, TMR_SELECT_CHANNEL_1, &tmr_oc_init_structure);
    tmr_channel_value_set(TMR5, TMR_SELECT_CHANNEL_1, 0);
    tmr_output_channel_buffer_enable(TMR5, TMR_SELECT_CHANNEL_1, TRUE);

    tmr_period_buffer_enable(TMR5, TRUE);

    /* tmr enable counter */
    tmr_counter_enable(TMR5, TRUE);
    #endif

    uint16_t timerperiod = 0;
    uint16_t channel1pulse = 0;
    /* tmr1 clock enable */
    crm_periph_clock_enable(CRM_TMR1_PERIPH_CLOCK, TRUE);
    crm_periph_clock_enable(CRM_GPIOA_PERIPH_CLOCK, TRUE);

    /* timer1 output pin Configuration */
    gpio_init_struct.gpio_pins = GPIO_PINS_8;
    gpio_init_struct.gpio_mode = GPIO_MODE_MUX;
    gpio_init_struct.gpio_out_type = GPIO_OUTPUT_PUSH_PULL;
    gpio_init_struct.gpio_pull = GPIO_PULL_NONE;
    gpio_init_struct.gpio_drive_strength = GPIO_DRIVE_STRENGTH_STRONGER;
    gpio_init(GPIOA, &gpio_init_struct);

    gpio_pin_mux_config(GPIOA, GPIO_PINS_SOURCE8, GPIO_MUX_1);
    /* tmr1 configuration ---------------------------------------------------
    generate 7 pwm signals with 4 different duty cycles:
    prescaler = 0, tmr1 counter clock = apb2_freq *2

    the objective is to generate 7 pwm signal at 17.57 khz:
     - tim1_period = (apb2_freq * 2 / 17570) - 1
    the channel 1 and channel 1n duty cycle is set to 50%
    the channel 2 and channel 2n duty cycle is set to 37.5%
    the channel 3 and channel 3n duty cycle is set to 25%
    the channel 4 duty cycle is set to 12.5%
    the timer pulse is calculated as follows:
     - channelxpulse = dutycycle * (tim1_period - 1) / 100
    ----------------------------------------------------------------------- */
    /* compute the value to be set in arr regiter to generate signal frequency at 17.57 khz */
    timerperiod = 65535;//((crm_clocks_freq_struct.apb2_freq * 2) / 450 ) - 1;
    /* compute ccr1 value to generate a duty cycle at 10% for channel 1 and 1n */
    channel1pulse = (uint16_t) (((uint32_t) (timerperiod - 1)) / 2);

    tmr_base_init(TMR1, timerperiod, 0);
    tmr_cnt_dir_set(TMR1, TMR_COUNT_UP);

    /* channel 1 configuration in output mode */
    tmr_output_default_para_init(&tmr_output_struct);
    tmr_output_struct.oc_mode = TMR_OUTPUT_CONTROL_PWM_MODE_B;
    tmr_output_struct.oc_output_state = TRUE;
    tmr_output_struct.oc_polarity = TMR_OUTPUT_ACTIVE_LOW;
    tmr_output_struct.oc_idle_state = TRUE;
    tmr_output_struct.occ_output_state = TRUE;
    tmr_output_struct.occ_polarity = TMR_OUTPUT_ACTIVE_HIGH;
    tmr_output_struct.occ_idle_state = FALSE;
    /* channel 1 */
    tmr_output_channel_config(TMR1, TMR_SELECT_CHANNEL_1, &tmr_output_struct);
    tmr_channel_value_set(TMR1, TMR_SELECT_CHANNEL_1, channel1pulse);

    /* tmr1 output enable */
    tmr_output_enable(TMR1, FALSE);
    /* enable tmr1 */
    tmr_counter_enable(TMR1, FALSE);
}

//key drv
__IO uint8_t func_key_cnt = 0;
__IO uint8_t func_key_code = 0;
__IO uint8_t func_key_fun = CODE_NONE;

void Key_Init(void)
{
    func_key_cnt = 0;
    func_key_code = 0;
    func_key_fun = CODE_NONE;

    //key init
}

void Button_handle(void)
{
    if(func_key_code == 0)
    {
        if(KEYL_READ() == FUNC_KEY_ACTIVE)
        {
            func_key_code = 1;
        }
    }
    else if(func_key_code == 1)
    {
        if(KEYL_READ() == FUNC_KEY_ACTIVE)
        {
            func_key_code = 2;
        }
        else
        {
            func_key_code = 0;
        }

        func_key_cnt = 0;
    }
    else if(func_key_code == 2)
    {
        if(KEYL_READ() == FUNC_KEY_ACTIVE)
        {
            func_key_cnt ++;

            //50 * 24 = 1.2s
            if(func_key_cnt > 20)
            {
                //长按
                func_key_fun = CODE_L_CLICK;
                func_key_code = 3;
            }
        }
        //单击释放
        else
        {
            func_key_code = 4;
            func_key_cnt = 0;
        }
    }
    else if(func_key_code == 3)
    {
        //长按待释放
        if(KEYL_READ() != FUNC_KEY_ACTIVE)
        {
            func_key_code = 0;
            func_key_cnt = 0;
        }
    }
    else if(func_key_code == 4)
    {
        if(KEYL_READ() == FUNC_KEY_ACTIVE)
        {
            func_key_fun = CODE_D_CLICK;
            func_key_code = 5;
            func_key_cnt = 0;
        }
        else
        {
            //50 * 4 = 200ms
            func_key_cnt ++;

            if(func_key_cnt > 4)
            {
                func_key_fun = CODE_CLICK;
                func_key_code = 0;
                func_key_cnt = 0;
            }
        }
    }
    else if(func_key_code == 5)
    {
        if(KEYL_READ() != FUNC_KEY_ACTIVE)
        {
            func_key_code = 0;
            func_key_cnt = 0;
        }
    }
}

__IO uint8_t ENC_TAB[4] = {0, 2, 3, 1};
__IO uint8_t g_enc_old_sta[2];
__IO uint8_t enc_code[2] = {0,};

uint8_t Check_enc(void)
{
    uint8_t res = 0;
    uint8_t enc_status;

    if(1)
    {
        enc_status = ENC1_READ();

        if(((enc_status == ENC_TAB[0]) && (g_enc_old_sta[0] == ENC_TAB[1])) || \
                ((enc_status == ENC_TAB[1]) && (g_enc_old_sta[0] == ENC_TAB[2])) || \
                ((enc_status == ENC_TAB[2]) && (g_enc_old_sta[0] == ENC_TAB[3])) || \
                ((enc_status == ENC_TAB[3]) && (g_enc_old_sta[0] == ENC_TAB[0])))
        {
            res = ENC_CODE_RIGHT;
        }
        else if(((enc_status == ENC_TAB[0]) && (g_enc_old_sta[0] == ENC_TAB[3])) || \
                ((enc_status == ENC_TAB[1]) && (g_enc_old_sta[0] == ENC_TAB[0])) || \
                ((enc_status == ENC_TAB[2]) && (g_enc_old_sta[0] == ENC_TAB[1])) || \
                ((enc_status == ENC_TAB[3]) && (g_enc_old_sta[0] == ENC_TAB[2])))
        {
            res = ENC_CODE_LEFT;
        }

        g_enc_old_sta[0] = enc_status;
    }

    enc_code[0] = res;
    return res;
}
